package pseudoAssemblerCompiler.twopassassembler.view.firstpass;

import org.apache.commons.lang.StringUtils;
import org.eclipse.jface.text.source.*;
import org.eclipse.jface.text.Document;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.CTabFolder2Listener;
import org.eclipse.swt.custom.CTabFolderEvent;
import org.eclipse.swt.custom.StyleRange;
import org.eclipse.swt.custom.StyledText;
import org.eclipse.swt.events.ModifyEvent;
import org.eclipse.swt.events.ModifyListener;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.layout.FormAttachment;
import org.eclipse.swt.layout.FormData;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.MessageBox;
import org.eclipse.ui.texteditor.DefaultMarkerAnnotationAccess;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import pseudoAssemblerCompiler.twopassassembler.view.common.IView;
import pseudoAssemblerCompiler.twopassassembler.view.util.CTabFolderContainer;

import java.util.HashMap;
import java.util.Map;

/**
 * Нижний контейнер, куда выводятся все ошибки
 * и двоичный код программы
 *
 * @author Чекашов Р. И.
 */
public class Editor implements IView, IEditor {

    private static final Logger LOGGER =
            LoggerFactory.getLogger(Editor.class);

    private CTabFolderContainer _tabFolder;

    private Map<String, StyledText> _editTabs;

    public Editor(Composite aParent) {
        _tabFolder = new CTabFolderContainer(aParent);
        _editTabs = new HashMap<String, StyledText>();
        listeners();
    }

    /**
     * Располагаем элементы в определённом порядке
     */
    private void layouts(Control text) {
        FormData data;

        //Sash - переплёт
        data = new FormData();
        data.top = new FormAttachment(0, 0); // Attach to top
        data.left = new FormAttachment(0, 0); // Attach halfway across
        data.bottom = new FormAttachment(100, 0); // Attach to bottom
        data.right = new FormAttachment(100, 0);
        text.setLayoutData(data);
    }

    public String getText() {
        String text = _editTabs.get(_tabFolder.get_cTabFolder().getSelection().getText()).getText();

        return text;
    }

    @Override
    public void setLayoutData(Object layoutData) {
//        _composite.setLayoutData(layoutData);
    }

    @Override
    public void show() {
//        layouts();
    }

    @Override
    public Composite getComposite() {
        return null;
    }

    @Override
    public void setController(Object controller) {
        //this method do nothing
    }

    @Override
    public StyledText openNewEditTab(String programName) {
        Composite composite = _tabFolder.createCTabItem(programName);
//        VerticalRuler verticalRuler = new VerticalRuler(10);
        LineNumberRulerColumn lineNumberRulerColumn = new LineNumberRulerColumn();
        AnnotationRulerColumn annotationRulerColumn =
                new AnnotationRulerColumn(10);
//        annotationRulerColumn.addAnnotationType("MARKER");

        CompositeRuler compositeRuler = new CompositeRuler();
        compositeRuler.addDecorator(0, lineNumberRulerColumn);
        compositeRuler.addDecorator(1, annotationRulerColumn);

        SourceViewer viewer = new SourceViewer(composite, compositeRuler,
                SWT.MULTI | SWT.BORDER | SWT.V_SCROLL | SWT.H_SCROLL);
//        viewer.configure(new MinimalSourceViewerConfiguration());
        viewer.setDocument(new Document());

//        StyledText newProgramText =
//                new StyledText(composite, SWT.BORDER | SWT.MULTI | SWT.V_SCROLL);
        _editTabs.put(programName, viewer.getTextWidget());
        layouts(viewer.getControl());
        composite.layout();
        _styledText = viewer.getTextWidget();
        _styledText.addModifyListener(new ModifyListener() {
            @Override
            public void modifyText(ModifyEvent modifyEvent) {
                hideError();
            }
        });
        return viewer.getTextWidget();
//        return null;
    }

    private StyledText _styledText;

    private int _start;
    private int _length;

    public void showError(int start, int len) {
        _start = start;
        _length = len;
        Color red = new Color(Display.getCurrent(), 255, 45, 45);
        StyleRange styleRange = new StyleRange();
        styleRange.start = start;
        styleRange.length = len;
        styleRange.fontStyle = SWT.BOLD;
        styleRange.foreground = red;
        styleRange.underline = true;
        styleRange.underlineColor = red;
        styleRange.underlineStyle = SWT.UNDERLINE_ERROR;
        _styledText.setStyleRange(styleRange);
    }

    public void hideError() {
        Color black = new Color(Display.getCurrent(), 0, 0, 0);
        StyleRange styleRange = new StyleRange();
        styleRange.start = 0;
        styleRange.length = _styledText.getText().length();
        styleRange.fontStyle = SWT.NORMAL;
        styleRange.foreground = black;
        styleRange.underline = false;
        _styledText.setStyleRange(styleRange);
    }

    private void listeners() {
        // Add a listener to get the close button on each tab
        _tabFolder.get_cTabFolder().addCTabFolder2Listener(new CTabFolder2Listener() {
            @Override
            public void close(CTabFolderEvent event) {
                String msg = String.format("Сохранить файл [%s]?", _tabFolder.get_cTabFolder().getSelection().getText());
                MessageBox mb = new MessageBox(_tabFolder.get_cTabFolder().getShell(),
                        SWT.ICON_QUESTION | SWT.YES | SWT.NO | SWT.CANCEL);
                mb.setMessage(msg);
                switch (mb.open()) {
                    case SWT.YES:
                        LOGGER.debug("Program has been saved!");
                        break;
                    case SWT.NO:
                        break;
                    case SWT.CANCEL:
                        event.doit = false; // Cancel the event processing, so tab stays open
                        break;
                    default:
                        LOGGER.debug("Smth wrong!");
                        break;
                }

            }

            @Override
            public void minimize(CTabFolderEvent event) {
                //this method do nothing
            }

            @Override
            public void maximize(CTabFolderEvent event) {
                //this method do nothing
            }

            @Override
            public void restore(CTabFolderEvent event) {
                //this method do nothing
            }

            @Override
            public void showList(CTabFolderEvent event) {
                //this method do nothing
            }
        });
    }

}
